package com.yxsk.relay.job.component.common.protocol.message.base;

import lombok.*;

import java.io.Serializable;

/**
 * @date 2018/7/22
 */
@Getter
@Setter
@ToString(callSuper = true)
@NoArgsConstructor
@Builder
@AllArgsConstructor
public final class ResultResponse<T> extends Response implements Serializable {

    public static final String SUCCESS_CODE = ResponseCodes.SUCCESS.getCode();

    private T data;

    /**
     * 构建请求成功的返回报文，仅包含message消息字段
     * 常用用于客户端请求数据新建和更新操作，提示操作成功
     *
     * @param message 操作提示消息
     * @return
     */
    public static ResultResponse ok(String message) {
        return ResultResponse.of(SUCCESS_CODE, message, null);
    }

    /**
     * 构建请求成功的返回报文，仅包含data数据字段
     * 常用用于客户端请求表单或列表数据
     *
     * @param data 请求表单或列表数据
     * @return
     */
    public static <T> ResultResponse ok(T data) {
        return ResultResponse.of(SUCCESS_CODE, null, data);
    }

    /**
     * 构建请求成功的返回报文，包含message消息字段和data数据字段
     *
     * @param message 操作提示消息
     * @param data    请求表单或列表数据
     * @return
     */
    public static <T> ResultResponse ok(String message, T data) {
        return ResultResponse.of(SUCCESS_CODE, message, data);
    }

    /**
     * 构建请求失败的返回报文，包含错误码信息和message消息字段
     *
     * @param errorCode 错误码
     * @param message   操作提示消息
     * @return
     */
    public static ResultResponse fail(String errorCode, String message) {
        return ResultResponse.of(errorCode, message, null);
    }

    /**
     * 构建请求失败的返回报文，包含错误码信息和data数据字段
     * 通常来说，不常用，失败一般只需要返回对应的错误码和消息字段即可
     *
     * @param errorCode 错误码
     * @param data      错误数据详情
     * @return
     */
    public static <T> ResultResponse fail(String errorCode, T data) {
        return ResultResponse.of(errorCode, null, data);
    }

    /**
     * 构建请求失败的返回报文，包含错误码信息、消息字段和data数据字段
     * 通常来说，不常用，失败一般只需要返回对应的错误码和消息字段即可
     *
     * @param errorCode 错误码
     * @param message   操作提示消息
     * @param data      错误数据详情
     * @return
     */
    public static <T> ResultResponse fail(String errorCode, String message, T data) {
        return ResultResponse.of(errorCode, message, data);
    }

    private static <T> ResultResponse of(String code, String message, T data) {
        ResultResponse<Object> response = ResultResponse.builder()
                .data(data)
                .build();
        response.setCode(code);
        response.setMessage(message);
        return response;
    }

    public static boolean isOk(Response response) {
        if (response == null) {
            return false;
        }
        return SUCCESS_CODE.equals(response.code);
    }

}

